<template>
  <div class="flex h-full min-w-[300px] flex-col">
    <div :class="['response-head', props.isExpanded ? '' : 'border-t']">
      <div class="flex items-center justify-between">
        <template v-if="props.activeLayout === 'vertical'">
          <MsButton
            v-if="props.isExpanded"
            type="icon"
            class="!mr-0 !rounded-full bg-[rgb(var(--primary-1))]"
            size="small"
            @click="emit('changeExpand', false)"
          >
            <icon-down :size="8" />
          </MsButton>
          <MsButton
            v-else
            type="icon"
            status="secondary"
            class="!mr-0 !rounded-full"
            size="small"
            @click="emit('changeExpand', true)"
          >
            <icon-right :size="8" />
          </MsButton>
        </template>
        <div
          v-if="props.isEdit && props.request.response.requestResults[0]?.responseResult?.responseCode"
          class="ml-[4px] flex items-center"
        >
          <MsButton
            type="text"
            :class="['font-medium', activeResponseType === 'content' ? '' : '!text-[var(--color-text-n4)]']"
            @click="() => setActiveResponse('content')"
          >
            {{ t('apiTestDebug.responseContent') }}
          </MsButton>
          <a-divider direction="vertical" :margin="4"></a-divider>
          <MsButton
            type="text"
            :class="['font-medium', activeResponseType === 'result' ? '' : '!text-[var(--color-text-n4)]']"
            @click="() => setActiveResponse('result')"
          >
            {{ t('apiTestManagement.executeResult') }}
          </MsButton>
        </div>
        <div v-else class="ml-[4px] mr-[24px] font-medium">{{ t('apiTestDebug.responseContent') }}</div>
        <a-radio-group
          v-if="!props.hideLayoutSwitch"
          v-model:model-value="innerLayout"
          type="button"
          size="small"
          @change="(val) => emit('changeLayout', val as Direction)"
        >
          <a-radio value="vertical">{{ t('apiTestDebug.vertical') }}</a-radio>
          <a-radio value="horizontal">{{ t('apiTestDebug.horizontal') }}</a-radio>
        </a-radio-group>
      </div>
      <div
        v-if="props.request.response.requestResults[0]?.responseResult?.responseCode"
        class="flex items-center justify-between gap-[24px]"
      >
        <a-popover position="left" content-class="response-popover-content">
          <div :style="{ color: statusCodeColor }">
            {{ props.request.response.requestResults[0].responseResult.responseCode }}
          </div>
          <template #content>
            <div class="flex items-center gap-[8px] text-[14px]">
              <div class="text-[var(--color-text-4)]">{{ t('apiTestDebug.statusCode') }}</div>
              <div :style="{ color: statusCodeColor }">
                {{ props.request.response.requestResults[0].responseResult.responseCode }}
              </div>
            </div>
          </template>
        </a-popover>
        <a-popover position="left" content-class="w-[400px]">
          <div class="one-line-text text-[rgb(var(--success-7))]">
            {{ props.request.response.requestResults[0].responseResult.responseTime }} ms
          </div>
          <template #content>
            <div class="mb-[8px] flex items-center gap-[8px] text-[14px]">
              <div class="text-[var(--color-text-4)]">{{ t('apiTestDebug.responseTime') }}</div>
              <div class="text-[rgb(var(--success-7))]">
                {{ props.request.response.requestResults[0].responseResult.responseTime }} ms
              </div>
            </div>
            <responseTimeLine :response-timing="timingInfo" />
          </template>
        </a-popover>
        <a-popover position="left" content-class="response-popover-content">
          <div class="one-line-text text-[rgb(var(--success-7))]">
            {{ props.request.response.requestResults[0].responseResult.responseSize }} bytes
          </div>
          <template #content>
            <div class="flex items-center gap-[8px] text-[14px]">
              <div class="text-[var(--color-text-4)]">{{ t('apiTestDebug.responseSize') }}</div>
              <div class="one-line-text text-[rgb(var(--success-7))]">
                {{ props.request.response.requestResults[0].responseResult.responseSize }} bytes
              </div>
            </div>
          </template>
        </a-popover>
        <!-- <a-popover position="left" content-class="response-popover-content">
          <div class="text-[var(--color-text-1)]">{{ props.request.response.env }}</div>
          <template #content>
            <div class="flex items-center gap-[8px] text-[14px]">
              <div class="text-[var(--color-text-4)]">{{ t('apiTestDebug.runningEnv') }}</div>
              <div class="text-[var(--color-text-1)]">{{ props.request.response.env }}</div>
            </div>
          </template>
        </a-popover>
        <a-popover position="left" content-class="response-popover-content">
          <div class="text-[var(--color-text-1)]">{{ props.request.response.resource }}</div>
          <template #content>
            <div class="flex items-center gap-[8px] text-[14px]">
              <div class="text-[var(--color-text-4)]">{{ t('apiTestDebug.resourcePool') }}</div>
              <div class="text-[var(--color-text-1)]">{{ props.request.response.resource }}</div>
            </div>
          </template>
        </a-popover> -->
      </div>
    </div>
    <a-spin :loading="props.loading" class="h-[calc(100%-35px)] w-full px-[18px] pb-[18px]">
      <edit
        v-if="props.isEdit && activeResponseType === 'content' && props.responseDefinition"
        v-model:activeTab="activeTab"
        :response="props.responseDefinition"
        :upload-temp-file-api="props.uploadTempFileApi"
        @change="handleResponseChange"
      />
      <result
        v-else-if="!props.isEdit || (props.isEdit && activeResponseType === 'result')"
        v-model:activeTab="activeTab"
        :request="props.request"
      />
    </a-spin>
  </div>
</template>

<script setup lang="ts">
  import { useVModel } from '@vueuse/core';

  import MsButton from '@/components/pure/ms-button/index.vue';
  import type { Direction } from '@/components/pure/ms-split-box/index.vue';
  import edit from './edit.vue';
  import result from './result.vue';
  import responseTimeLine from '@/views/api-test/components/responseTimeLine.vue';

  import { useI18n } from '@/hooks/useI18n';

  import { ResponseDefinition } from '@/models/apiTest/common';
  import { ResponseComposition } from '@/enums/apiEnum';

  import type { RequestParam } from '../index.vue';

  const props = withDefaults(
    defineProps<{
      activeTab: ResponseComposition;
      activeLayout?: Direction;
      isExpanded: boolean;
      responseDefinition?: ResponseDefinition;
      request: RequestParam;
      hideLayoutSwitch?: boolean; // 隐藏布局切换
      loading?: boolean;
      isEdit?: boolean; // 是否可编辑
      uploadTempFileApi?: (...args) => Promise<any>; // 上传临时文件接口
    }>(),
    {
      activeLayout: 'vertical',
      hideLayoutSwitch: false,
    }
  );
  const emit = defineEmits<{
    (e: 'update:activeLayout', value: Direction): void;
    (e: 'update:activeTab', value: ResponseComposition): void;
    (e: 'changeExpand', value: boolean): void;
    (e: 'changeLayout', value: Direction): void;
    (e: 'change'): void;
  }>();

  const { t } = useI18n();

  const innerLayout = useVModel(props, 'activeLayout', emit);
  const activeTab = useVModel(props, 'activeTab', emit);
  // 响应时间信息
  const timingInfo = computed(() => {
    const {
      dnsLookupTime,
      downloadTime,
      latency,
      responseTime,
      socketInitTime,
      sslHandshakeTime,
      tcpHandshakeTime,
      transferStartTime,
    } = props.request.response.requestResults[0].responseResult;
    return {
      dnsLookupTime,
      tcpHandshakeTime,
      sslHandshakeTime,
      socketInitTime,
      latency,
      downloadTime,
      transferStartTime,
      responseTime,
    };
  });
  // 响应状态码对应颜色
  const statusCodeColor = computed(() => {
    const code = props.request.response.requestResults[0].responseResult.responseCode;
    if (code >= 200 && code < 300) {
      return 'rgb(var(--success-7)';
    }
    if (code >= 300 && code < 400) {
      return 'rgb(var(--warning-7)';
    }
    return 'rgb(var(--danger-7)';
  });

  function handleResponseChange() {
    emit('change');
  }

  const activeResponseType = ref<'content' | 'result'>('content');

  function setActiveResponse(val: 'content' | 'result') {
    activeResponseType.value = val;
  }
</script>

<style lang="less">
  .response-popover-content {
    padding: 4px 8px;
    .arco-popover-content {
      @apply mt-0;

      font-size: 14px;
      line-height: 22px;
    }
  }
</style>

<style lang="less" scoped>
  .response-head {
    @apply flex flex-wrap items-center justify-between border-b;

    padding: 8px 16px;
    border-color: var(--color-text-n8);
    gap: 8px;
  }
</style>
